/*--------------------------------
一、视图序列和索引
1、视图
   视图是对数据查询操作结果集的一种存储方式；
   视图是一种逻辑结构，不像物理表一样进行物理存储；
   视图只存储其创建的方式【select语句】，每次会话使用视图时都是临时进行查询的；
   在一次会话中视图的查询结果是可以进行缓存的【服务器端】；
    也可以这样理解：视图就是进行命名之后的子查询；
    视图也可以像物理表一样进行dml和查询操作；但是一般视图常用语查询操作，尽量避免对视图进行dml操作；
   视图可以将多个物理表的信息进行展示【通过关联子查询实现】【最常用功能】
   
   
   语法：
       create  or replace view 用户名.视图名
              as select 子查询；
   解析：
       （1）视图名的命名规范按照表的命名规范即可；一般习惯为：view_物理表1_物理表2
       （2）视图是临时缓存的；视图是对物理表的一种”查看的视觉窗口“
       （3）通过视图可以对用屏蔽器不可见内容，仅对其展示其可见的内容；【具有数据查看的权限管理性】
       （3）视图可以像物理表一样进行查询操作；
       （4）如果子查询是多表关联查询，则需要注意子查询的显示列表中不要存在重名字段名；
       （5）如果加上 replace则如果视图已存在，则会被替换；

   补充：
       如果在创建视图时，提示权限不足，则说明当前用户没有创建视图的权限；
       需要切换到系统管理员账户，例如 sys等，然后执行以下权限赋值语句：
       grant 权限列表|角色名 to 用户名|角色名|public [with grant option] 
       
       注意：如果带有with语句，表明被赋值权限的用户，还可以把权限赋给其他用户；
   
   视图的分类：
       简单视图：只有一个物理表，创建视图的子查询中不包含函数、分组操作；
           简单视图可以进行dml操作；并不是所有的简单视图都可以进行dml操作；
           具体要求参考教材：P126；
           
       复杂视图：有一个或多个物理表，创建视图的子查询中包含了函数、分组操作；
           复杂视图不能进行dml操作；
           
2、序列
   序列是制定开始值，以及自增步长的一个逐步自增的有序数列；
   特点：
       按步长自增，不能跳跃；
       只能自增不能自减；
       可以保证序列的每个数都是唯一的；
       主要的用途是作为主键、唯一键的值；
       Oracle中序列和触发器配合使用可以实现主键的自增功能；
       
       语法：
           create sequence 用户名.序列名 
                --- 以下参数都可以省略
                increment by n             -- 步长【默认1】
                start with n               -- 初始值【默认1】
                maxvalue n | nomaxvalue    --最大值【1027】|无最大值
                minvalue n | nominvalue    --最小值【-1026】 | 无最小值
                cycle | nocycle            -- 循环 | 不循环【默认】
                catche n | nocatche        --缓存【默认20个】 | 不适用缓存
        解析：        
             注意sequence命名规范，前缀_表名_字段名[_后缀]；
             一个sequence对象可以由多个表同时使用，但是一般在项目中一个sequence只供一个表的一个字段使用；      
     序列sequence的使用：
         sequence有两个伪属性：
             nextval：返回下一个可用的值；
             currval：返回当前的序列值；【初次使用时，nextval在currval之前执行】  
             
     修改序列：
         可以使用 alter sequence 进行修改；
         注意，start with参数不可以修改；
     删除序列：
         drop sequence 序列名;
         可以删除序列；和删除表是一样；
         
3、索引
   索引是为了提高字段中的查找速度而建立的查找的引用目录；
   索引提供了对表中的数据直接和快速的访问途径；
   索引的目的是快速定位数据；如果没有索引只能进行逐步全表扫描；
   索引的在每次进行dml操作时都需要进行更新【需要进行维护，产生系统开销】
   所以并不是索引建立越多速度越快；
   唯一键Oracle会自动创建索引；
   创建索引是数据库性能优化的一个方面；
   
   
   推荐使用索引情况：
       数据量足够到；
       查询操作较多，而且查询的数据量在整体中只占很少一部分；
       新增、删除、修改操作较少；【每新增、删除、修改一条记录，则需要重新构建索引】
       文本或字符串类型的字段优先考虑创建索引；
   不推荐使用索引：
       反之；                         
   
   创建语法：
       create index 用户名.索引名
              on 表名(字段列表);
              
   删除索引：
       drop index 索引名;   
       
                            
--------------------------------*/
--- 给hr赋值 create any view 的权限，需要先切换为系统管理账户（sys）
-- 使用sys账户执行以下语句
grant create any view to hr;

-- 显示部门编号为60的员工信息以及部门信息
select e.*,d.* from employees e,departments d where e.department_id = d.department_id;
-- 创建一个联合查询的视图
create view view_emp_dept as
       select e.*,d.department_name,d.location_id from employees e,departments d 
              where e.department_id = d.department_id;

-- 查询视图
select * from view_emp_dept ved where ved.DEPARTMENT_ID = 60;

--- 视图的dml操作
--- 创建一个物理表
create table depts30 (
dept_id number(11) constraint depts30_deptId_pk primary key,
dept_name varchar2(20),
manager_id  number(11) not null,
dept_loc  number(11)
);
--- 插入数据
insert into depts30(dept_id,dept_name,manager_id,dept_loc) 
select * from departments d where d.manager_id is not null;

--- 创建一个简单视图进行dml操作
create or replace view view_depts30 as
       select * from depts30;
-- 通过视图查询数据
select * from  view_depts30;
--- 通过视图插入一条记录【注意：实际项目中尽量避免通过视图进行dml操作】
insert into view_depts30 values(1001,'后勤部',260,300000);

---------序列-------------
--- 创建一个序列，供表depts30使用
create sequence seq_depts30_deptId 
       increment by 1
       start with 1002
       nomaxvalue
       nocycle
       nocache

--- 插叙sequence的伪属性
select  seq_depts30_deptId.nextval from dual;
select seq_depts30_deptId.Currval from dual;

-- 在insert语句中使用sequence
insert into depts30 values(seq_depts30_deptId.nextval,'后勤部2',260,300000);

-- 查看数据
select * from depts30;